// 创建用户相关的小仓库
import {defineStore} from 'pinia'
// 引入接口
import { reqLogin,reqUserInfo,reqLogout } from '@/api/user'
// 引入数据类型
import {type UserState} from './types/type'
import type { loginFromData,loginResponseData,userInfoResponseData  } from '@/api/user/type'
// 引入操作本地存储的工具方法
import { SET_ITEM,GET_ITEM,REMOVE_ITEM } from '@/utills/token'
// 引入路由（常量路由）
import { constantRoute,asyncRoute,anyRoute } from '@/router/routes'
// 引入路由器对象
import router from '@/router'
// 引入深拷贝方法
// @ts-ignore
import cloneDeep from 'lodash/cloneDeep'

// 用于过滤当前用户需要展示的异步路由
function filterAsyncRoute(asyncRoute:any,routes:any){
    return asyncRoute.filter((item:any)=>{
        if(routes.includes(item.name)){
            if(item.children&&item.children.length>0){
                item.children=filterAsyncRoute(item.children,routes)
            }
            return true
        }
    })
}

let useUserStore=defineStore('User',{
    // 存储数据
    state():UserState{
        return {
            "token": GET_ITEM(), // 用户唯一标识
            menuRoutes:constantRoute, // 存储生成菜单需要的数组（路由）
            username:'',
            avatar:'',
            // 存储当前用户是否包含某一个按钮
            buttons:[]
        }
    },
    // 处理异步、逻辑
    actions:{
        // 用户登录的方法
        async userLogin(data:loginFromData){
            // 登录请求
            let result:loginResponseData=await reqLogin(data)
            // 登录请求成功->200 token
            if(result.code==200){
                // pinia仓库存储以下token
                // 由于pinia/vuex存储数据其实是利用js对象
                this.token=(result.data as string)
                // 本地存储持久化存储一份
                SET_ITEM(result.data as string)
                // 保证当前async函数返回一个成功的promise对象
                return 'ok'
            }else{
                // 登录请求失败->201
                return Promise.reject(new Error(result.data))
            }
            
        },
        // 获取用户信息的方法
        async userInfo(){
            // 获取用户的信息存储到仓库中【名字、头像】
            let result:userInfoResponseData=await reqUserInfo()
            // 如果获取用户信息成功：存储一下用户信息
            if(result.code==200){
                this.username=result.data.name
                this.avatar=result.data.avatar
                this.buttons=result.data.buttons
                // 计算当前用户需要展示的异步路由
                let userAsyncRoute=filterAsyncRoute(cloneDeep(asyncRoute),result.data.routes)
                // 菜单需要的数据
                this.menuRoutes=[...constantRoute,...userAsyncRoute,...anyRoute]
                // 目前路由器管理的只有常量路由:用户计算完毕的异步路由、任意路由动态追加
                let routesAll=[...userAsyncRoute,...anyRoute]
                routesAll.forEach((route:any)=>{
                    router.addRoute(route)
                })
                return 'ok'
            }else{
                return Promise.reject(new Error(result.message))
            }
        },
        // 退出登录方法
        async userLogout(){
            // 发送退出登录请求
            let result:any=await reqLogout()
            if(result.code==200){
                // 清空数据
                this.token=''
                this.username=''
                this.avatar=''
                REMOVE_ITEM()
                return 'ok'
            }else{
                return Promise.reject(new Error(result.message))
            }
        }
    },
    getters:{

    }
})

// 对外暴露获取小仓库的方法
export default useUserStore